// ==UserScript==
// @name         sl-复星保德兴任务提醒
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  监控复星保德兴共享工作池超时任务（超过30分钟未处理）
// @author       AI Assistant
// @match        http://82.156.241.88:8090/*
// @grant        GM_notification
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_xmlhttpRequest
// @updateURL    https://gitee.com/i-recruit-handsome/i-attract-good-fortune/raw/master/sl-fxbdx.user.js
// @downloadURL  https://gitee.com/i-recruit-handsome/i-attract-good-fortune/raw/master/sl-fxbdx.user.js
// ==/UserScript==
(function() {
    'use strict';
    // ==================== 配置项 ====================
    const CONFIG = {
        DEBUG_MODE: false, // 调试模式：true=显示调试信息，false=关闭调试信息
        DINGTALK_WEBHOOK: ' ', // 钉钉机器人webhook地址（留空则不发送钉钉通知）
        CHECK_INTERVAL: 6 * 60 * 1000, // 检查间隔：8分钟
        NOTIFICATION_COOLDOWN: 3 * 60 * 1000, // 通知冷却期：3分钟
        NOTIFICATION_DISPLAY_TIME: 60 * 1000, // 通知显示时间：1分钟
        REMINDER_DELAY_MINUTES: 30, // 提醒延迟：录制后30分钟提醒
        CHECK_DAYS_BACK: 5 // 检查天数：检查包含多少天前的数据（0=仅今天，1=包含1天前，以此类推。例如设为30可检查30天前的数据）
    };

    // 调试日志函数
    function debugLog(...args) {
        if (CONFIG.DEBUG_MODE) {
            console.log(...args);
        }
    }
    // 全局变量
    let monitorTimer = null;
    let lastNotificationTime = 0;
    let isMonitoring = false;
    let overdueTasks = []; // 存储超时任务信息

    // 刷新数据（点击查询按钮）
    function refreshData() {
        try {
            const queryButton = document.querySelector('input.query_button[onclick*="queryEsDocMain()"]');
            if (queryButton) {
                queryButton.click();
            }
        } catch (error) {
            console.error('刷新数据失败:', error);
        }
    }

    // 获取需要提醒的任务数（录制时间+30分钟后需要提醒）
    function getSharedPoolOverdueCount() {
        try {
            debugLog('[调试] 开始检测需要提醒的任务...');
            debugLog(`[调试] 配置：提醒延迟=${CONFIG.REMINDER_DELAY_MINUTES}分钟，检查范围=包含${CONFIG.CHECK_DAYS_BACK}天前的数据`);

            // 尝试多种可能的表格选择器
            let table = document.querySelector('.datagrid-view2 .datagrid-btable');
            if (!table) {
                table = document.querySelector('.datagrid-view .datagrid-btable');
            }
            if (!table) {
                table = document.querySelector('.datagrid-btable');
            }
            if (!table) {
                debugLog('[调试] 未找到数据表格');
                return 0;
            }

            debugLog('[调试] 使用的表格选择器:', table.className);
            const rows = table.querySelectorAll('tr.datagrid-row');
            debugLog(`[调试] 找到 ${rows.length} 行数据`);
            if (rows.length === 0) return 0;

            const now = new Date();
            const checkStartDate = new Date(now);
            checkStartDate.setDate(checkStartDate.getDate() - CONFIG.CHECK_DAYS_BACK);
            checkStartDate.setHours(0, 0, 0, 0);

            overdueTasks = []; // 清空历史记录
            debugLog(`[调试] 当前时间: ${now.toLocaleString('zh-CN')}`);
            debugLog(`[调试] 检查范围: ${checkStartDate.toLocaleDateString('zh-CN')} 至今（包含${CONFIG.CHECK_DAYS_BACK}天前的数据）`);

            for (let i = 0; i < rows.length; i++) {
                const row = rows[i];
                debugLog(`[调试] 第${i+1}行HTML结构:`, row.outerHTML.substring(0, 200) + '...');

                // 获取录制日期、时间和投保单号
                const dateTd = row.querySelector('td[field="polapplydate"] .datagrid-cell');
                const timeTd = row.querySelector('td[field="rectime"] .datagrid-cell');
                const doccodeTd = row.querySelector('td[field="doccode"] .datagrid-cell');

                debugLog(`[调试] 第${i+1}行选择器结果: 日期=${!!dateTd}, 时间=${!!timeTd}, 单号=${!!doccodeTd}`);

                // 尝试其他可能的选择器
                if (!dateTd || !timeTd || !doccodeTd) {
                    const allTds = row.querySelectorAll('td');
                    debugLog(`[调试] 第${i+1}行所有td字段:`);
                    allTds.forEach((td, index) => {
                        const field = td.getAttribute('field');
                        const content = td.textContent.trim();
                        debugLog(`[调试]   td[${index}]: field="${field}", content="${content}"`);
                    });
                }

                if (dateTd && timeTd && doccodeTd) {
                    const dateStr = dateTd.textContent.trim();
                    const timeStr = timeTd.textContent.trim();
                    const doccode = doccodeTd.textContent.trim();

                    debugLog(`[调试] 处理任务 ${doccode}: 原始数据 - 日期=${dateStr}, 时间=${timeStr}`);

                    // 合并日期时间并解析
                    const datetimeStr = `${dateStr} ${timeStr}`;
                    const recordTime = new Date(datetimeStr);

                    // 检查日期解析是否成功
                    if (isNaN(recordTime.getTime())) {
                        debugLog(`[调试] ❌ 任务 ${doccode}: 日期时间解析失败 - ${datetimeStr}`);
                        continue;
                    }

                    debugLog(`[调试] 任务 ${doccode}: 解析后录制时间=${recordTime.toLocaleString('zh-CN')}`);

                    // 检查是否在指定天数范围内
                    if (recordTime < checkStartDate) {
                        debugLog(`[调试] ⏭️ 任务 ${doccode}: 录制时间(${recordTime.toLocaleDateString('zh-CN')})超出检查范围(${checkStartDate.toLocaleDateString('zh-CN')})，跳过`);
                        continue;
                    }

                    // 计算应该提醒的时间（录制时间 + 延迟分钟数）
                    const reminderTime = new Date(recordTime.getTime() + CONFIG.REMINDER_DELAY_MINUTES * 60 * 1000);
                    const timeDiff = now - recordTime;
                    const minutesDiff = timeDiff / (1000 * 60);
                    const isOverdue = now >= reminderTime;
                    const reminderDiff = (now - reminderTime) / (1000 * 60);

                    debugLog(`[调试] 任务 ${doccode}:`);
                    debugLog(`[调试]   - 录制时间: ${recordTime.toLocaleString('zh-CN')}`);
                    debugLog(`[调试]   - 应提醒时间: ${reminderTime.toLocaleString('zh-CN')}`);
                    debugLog(`[调试]   - 当前时间: ${now.toLocaleString('zh-CN')}`);
                    debugLog(`[调试]   - 距离录制: ${Math.floor(minutesDiff)}分钟`);
                    debugLog(`[调试]   - 距离应提醒: ${Math.floor(reminderDiff)}分钟`);
                    debugLog(`[调试]   - 是否应提醒: ${isOverdue}`);

                    // 如果当前时间已超过应提醒时间，则记录为需要提醒的任务
                    if (isOverdue) {
                        const overdueMinutes = Math.floor((now - reminderTime) / (1000 * 60));
                        overdueTasks.push({
                            doccode,
                            recordTime: datetimeStr,
                            reminderTime: reminderTime.toLocaleString('zh-CN'),
                            overdueMinutes: Math.max(0, overdueMinutes)
                        });
                        debugLog(`[调试] ⚠️ 发现需要提醒的任务: ${doccode} (应在${reminderTime.toLocaleString('zh-CN')}提醒，已延迟${overdueMinutes}分钟)`);
                    } else {
                        const remainingMinutes = Math.ceil((reminderTime - now) / (1000 * 60));
                        debugLog(`[调试] ⏰ 任务 ${doccode}: 还需等待${remainingMinutes}分钟后提醒`);
                    }
                } else {
                    debugLog(`[调试] ❌ 第${i+1}行: 缺少必要字段 - 日期:${!!dateTd}, 时间:${!!timeTd}, 单号:${!!doccodeTd}`);
                }
            }
            debugLog(`[调试] 检测完成，共发现 ${overdueTasks.length} 个需要提醒的任务`);
            return overdueTasks.length;
        } catch (error) {
            debugLog('[调试] 获取需要提醒的任务失败:', error);
            return 0;
        }
    }

    // 发送钉钉通知
    function sendDingTalkNotification(message) {
        if (!CONFIG.DINGTALK_WEBHOOK) {
            debugLog('[调试] 钉钉webhook未配置，跳过钉钉通知');
            return;
        }

        try {
            const payload = {
                msgtype: 'text',
                text: {
                    content: message
                }
            };

            GM_xmlhttpRequest({
                method: 'POST',
                url: CONFIG.DINGTALK_WEBHOOK,
                headers: {
                    'Content-Type': 'application/json'
                },
                data: JSON.stringify(payload),
                onload: function(response) {
                    if (response.status === 200) {
                        debugLog('[调试] 钉钉通知发送成功');
                    } else {
                        debugLog('[调试] 钉钉通知发送失败:', response.status, response.responseText);
                    }
                },
                onerror: function(error) {
                    debugLog('[调试] 钉钉通知发送异常:', error);
                },
                ontimeout: function() {
                    debugLog('[调试] 钉钉通知发送超时');
                },
                timeout: 10000 // 10秒超时
            });
        } catch (error) {
            debugLog('[调试] 钉钉通知发送异常:', error);
        }
    }

    // 发送通知（简洁统计信息）
    function sendNotifications(overdueCount) {
        debugLog(`[调试] 准备发送通知，超时任务数: ${overdueCount}`);
        if (overdueCount === 0) {
            debugLog('[调试] 无超时任务，跳过通知');
            return;
        }

        const message = `待质检有${overdueCount}个任务,超过30分钟未处理!请及时处理!`;

        debugLog('[调试] 构建通知消息:', message);
        debugLog('[调试] 超时任务详情:');
        overdueTasks.forEach((task, index) => {
            debugLog(`[调试]   ${index + 1}. ${task.doccode} (录制时间:${task.recordTime}, 延迟${task.overdueMinutes}分钟)`);
        });

        debugLog('[调试] 发送系统通知消息');
        showLocalNotification(message, '复星保德兴任务提醒');

        // 异步发送钉钉通知
        setTimeout(() => {
            sendDingTalkNotification(message);
        }, 0);
    }

    // 显示本地通知
    function showLocalNotification(message, title = '复星保德兴任务提醒') {
        if (Notification.permission === 'granted') {
            const notification = new Notification(title, {
                body: message,
                tag: 'overdue-task-notification',
                requireInteraction: true,
                silent: false,
                renotify: true
            });
            notification.onclick = () => { window.focus(); notification.close(); };
            setTimeout(() => notification.close(), CONFIG.NOTIFICATION_DISPLAY_TIME);
        } else {
            alert(`${title}\n${message}`);
        }
    }

    // 检查并发送通知
    function checkAndNotify() {
        const now = Date.now();
        const timeSinceLastNotification = now - lastNotificationTime;
        const cooldownRemaining = CONFIG.NOTIFICATION_COOLDOWN - timeSinceLastNotification;

        debugLog(`[调试] 开始检查通知条件`);
        debugLog(`[调试] 距离上次通知: ${Math.floor(timeSinceLastNotification/1000)}秒`);
        debugLog(`[调试] 冷却期要求: ${CONFIG.NOTIFICATION_COOLDOWN/1000}秒`);

        if (timeSinceLastNotification >= CONFIG.NOTIFICATION_COOLDOWN) {
            debugLog('[调试] 通过冷却期检查，开始检测任务');
            const overdueCount = getSharedPoolOverdueCount();
            if (overdueCount > 0) {
                debugLog(`[调试] 🔔 触发通知条件，发送通知`);
                lastNotificationTime = now;
                sendNotifications(overdueCount);
                setTimeout(() => GM_setValue('lastNotificationTime', lastNotificationTime), 0);
            } else {
                debugLog('[调试] ✅ 无超时任务，无需通知');
            }
        } else {
            debugLog(`[调试] ⏳ 仍在冷却期，还需等待 ${Math.ceil(cooldownRemaining/1000)} 秒`);
        }
    }

    // 启动监控
    function startMonitoring() {
        if (isMonitoring) {
            debugLog('[调试] 监控已在运行中');
            return;
        }
        debugLog('[调试] 🚀 启动任务监控');
        debugLog(`[调试] 检查间隔: ${CONFIG.CHECK_INTERVAL/1000}秒`);
        debugLog(`[调试] 通知冷却期: ${CONFIG.NOTIFICATION_COOLDOWN/1000}秒`);

        isMonitoring = true;
        // 立即检查一次
        setTimeout(() => {
            debugLog('[调试] 执行首次检查');
            refreshData();
            setTimeout(checkAndNotify, 1500);
        }, 500);
        // 设置定时检查
        monitorTimer = setInterval(() => {
            debugLog('[调试] 执行定时检查');
            refreshData();
            setTimeout(checkAndNotify, 1500);
        }, CONFIG.CHECK_INTERVAL);
        updateToggleButton();
    }

    // 停止监控
    function stopMonitoring() {
        if (!isMonitoring) {
            debugLog('[调试] 监控未运行');
            return;
        }
        debugLog('[调试] 🛑 停止任务监控');
        isMonitoring = false;
        if (monitorTimer) {
            clearInterval(monitorTimer);
            monitorTimer = null;
        }
        updateToggleButton();
    }

    // 切换监控状态
    function toggleMonitoring() {
        if (isMonitoring) {
            stopMonitoring();
        } else {
            startMonitoring();
        }
        updateToggleButton();
    }

    // 更新按钮状态
    function updateToggleButton() {
        const button = document.getElementById('quality-check-monitor-btn');
        if (button) {
            button.value = isMonitoring ? '检测中' : '检测';
            button.style.backgroundColor = isMonitoring ? '#F44336' : '';
        }
    }

    // 检测是否存在包含queryEsDocMain()的查询按钮
    function checkTargetButton() {
        const queryButton = document.querySelector('input.query_button[onclick*="queryEsDocMain()"]');
        return queryButton !== null;
    }

    // 创建配置按钮（位于查询按钮旁）
    function createConfigButton() {
        // 先检测是否存在目标按钮
        if (!checkTargetButton()) {
            debugLog('未找到包含queryEsDocMain()的查询按钮，脚本不会在此页面运行');
            return false;
        }

        const queryButton = document.querySelector('input.query_button[onclick*="queryEsDocMain()"]');
        if (!queryButton) {
            debugLog('未找到查询按钮，等待加载...');
            // 每隔500ms检查一次查询按钮是否存在
            const checkInterval = setInterval(() => {
                const foundButton = document.querySelector('input.query_button[onclick*="queryEsDocMain()"]');
                if (foundButton) {
                    clearInterval(checkInterval);
                    insertButtonNextToQuery(foundButton);
                }
            }, 500);
            return true;
        }
        insertButtonNextToQuery(queryButton);
        return true;
    }

    // 在查询按钮右侧插入检测按钮
    function insertButtonNextToQuery(queryButton) {
        const checkButton = document.createElement('input');
        checkButton.type = 'button';
        checkButton.id = 'quality-check-monitor-btn';
        checkButton.value = '检测';
        checkButton.className = 'query_button'; // 继承查询按钮样式
        checkButton.style.marginLeft = '10px';
        checkButton.addEventListener('click', toggleMonitoring);

        const parent = queryButton.parentNode;
        parent.insertBefore(checkButton, queryButton.nextSibling);
    }

    // 初始化
    function init() {
        // 检测是否存在目标按钮，如果不存在则不初始化
        if (!checkTargetButton()) {
            return;
        }

        // 请求通知权限
        if (Notification.permission === 'default') {
            Notification.requestPermission();
        }
        // 恢复最后通知时间
        lastNotificationTime = GM_getValue('lastNotificationTime', 0);
        // 创建控制按钮（会自动等待查询按钮加载）
        const buttonCreated = createConfigButton();
        if (!buttonCreated) {
            debugLog('目标按钮检测失败，脚本不会运行');
            return;
        }
    }

    // 等待页面加载完成后初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();
